#!/bin/bash
# ═══════════════════════════════════════════════════════════════════════════════
# UltraDimension macOS GUI Installer Bootloader
# Copyright (c) 2024-2026 Shanghai UltraDimension Technology Co., Ltd.
#
# This script is embedded inside a macOS .app bundle as Contents/MacOS/installer.
# It uses osascript to show native macOS dialogs (license, progress, completion).
#
# Set at build time:
#   PRODUCT_NAME       e.g. "Claude Code" or "CodeX CLI"
#   PRODUCT_ID         e.g. "claude" or "codex"
#   INSTALLER_VERSION  e.g. "v5.11" or "v1.0"
# ═══════════════════════════════════════════════════════════════════════════════
set -euo pipefail

PRODUCT_NAME="CodeX CLI"
PRODUCT_ID="codex"
INSTALLER_VERSION="v1.0"

SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
APP_CONTENTS="$(dirname "$SCRIPT_DIR")"
RESOURCES_DIR="$APP_CONTENTS/Resources"
PAYLOAD_DIR="$APP_CONTENTS/payload"
WORK_DIR="$(mktemp -d /tmp/ud-installer-XXXXXXXX)"

cleanup() {
    rm -rf "$WORK_DIR"
    # Kill any rospo processes we started
    pkill -P $$ 2>/dev/null || true
}
trap cleanup EXIT

# ── osascript helpers ────────────────────────────────────────────────────────

show_license() {
    local license_text="$1"
    # Write license to temp file so osascript can read it cleanly
    local license_file="$WORK_DIR/license.txt"
    echo "$license_text" > "$license_file"

    osascript -e "
    set licensePath to POSIX file \"$license_file\"
    set licenseContent to read licensePath
    display dialog licenseContent ¬
        with title \"$PRODUCT_NAME License Agreement\" ¬
        buttons {\"Cancel\", \"I Agree\"} ¬
        default button \"I Agree\" ¬
        with icon note ¬
        giving up after 600
    " 2>/dev/null
}

show_token_input() {
    local raw
    raw=$(osascript -e "
    display dialog \"Enter your license token from the UltraDimension service portal:\" ¬
        default answer \"\" ¬
        with title \"$PRODUCT_NAME - License Verification\" ¬
        buttons {\"Cancel\", \"Verify\"} ¬
        default button \"Verify\" ¬
        with icon note
    " 2>/dev/null)
    # Cancel button produces "button returned:Cancel" (no "text returned:" prefix)
    if [[ "$raw" != "text returned:"* ]]; then
        return 1
    fi
    echo "${raw#text returned:}"
}

show_progress() {
    local phase="$1"
    local percent="$2"
    local detail="$3"
    echo "PROGRESS:${percent}:${phase}:${detail}"
}

show_done() {
    local success="$1"
    if [[ "$success" == "true" ]]; then
        osascript -e "
        display dialog \"$PRODUCT_NAME has been installed successfully.\\n\\nDesktop shortcuts:\\n  $PRODUCT_NAME\\n  $PRODUCT_NAME (Resume)\\n\\nYou may now close this window.\" ¬
            with title \"Installation Complete\" ¬
            buttons {\"Close\"} ¬
            default button \"Close\" ¬
            with icon note
        " 2>/dev/null
    else
        osascript -e "
        display dialog \"Installation did not complete.\\n\\nCheck the log file on your Desktop for details.\\n\\nCommon causes:\\n  - License validation failed\\n  - Rospo tunnel could not reach the server\\n  - Server-side agent reported an install failure\" ¬
            with title \"Installation Failed\" ¬
            buttons {\"Close\"} ¬
            default button \"Close\" ¬
            with icon stop
        " 2>/dev/null
    fi
}

# ── Payload extraction ───────────────────────────────────────────────────────

extract_payload() {
    mkdir -p "$WORK_DIR/payload"
    if [[ -d "$PAYLOAD_DIR" ]]; then
        cp -R "$PAYLOAD_DIR"/* "$WORK_DIR/payload/"
    elif [[ -f "$RESOURCES_DIR/payload.tar.gz" ]]; then
        tar xzf "$RESOURCES_DIR/payload.tar.gz" -C "$WORK_DIR/payload/"
    else
        echo "FATAL: No payload found in .app bundle"
        exit 1
    fi
    echo "Payload extracted to $WORK_DIR/payload"
}

# ── License token ────────────────────────────────────────────────────────────

read_license_token() {
    local token_file="$WORK_DIR/payload/license_token.txt"
    if [[ -f "$token_file" ]]; then
        cat "$token_file"
    fi
}

validate_license() {
    local token="$1"
    local resp
    resp=$(curl -s --max-time 10 "https://download.ultradimension.cn/api/auth/validate-license?token=${token}" 2>/dev/null || echo '{"ok":false}')
    if echo "$resp" | python3 -c "import json,sys; d=json.load(sys.stdin); sys.exit(0 if d.get('ok') else 1)" 2>/dev/null; then
        local phone
        phone=$(echo "$resp" | python3 -c "import json,sys; print(json.load(sys.stdin).get('user',{}).get('phone',''))" 2>/dev/null || echo "")
        echo "OK:$phone"
        return 0
    fi
    echo "FAIL"
    return 1
}

# ── Main flow ─────────────────────────────────────────────────────────────────

main() {
    # Extract embedded payload
    extract_payload

    # Phase 1: License
    local license_text
    license_text="$(cat <<'EOL'
========================================
  PRODUCT_NAME Remote Installer
  Version: INSTALLER_VERSION
  Copyright (c) 2024-2026
  Shanghai UltraDimension Technology Co., Ltd.
========================================

This is a user-initiated enterprise software deployment assistant.
Full source code: github.com/haiyichen001/UltraDimension-service

1. Service Description
   This tool installs:
   - Rospo SSH Tunnel (MIT license)
   - PRODUCT_NAME CLI
   - Portable Node.js runtime (if needed)

2. Trust Boundaries
   - No document collection or analytics telemetry
   - No bundled software or browser extensions
   - Tunnel service is removed after install

3. Security Transparency
   - All remote sessions: SSH + TLS 1.2 / AES-256
   - Engineer connection requires unique SSH key
   - Tunnel auto-closes after success, failure, or cancel

4. Privacy
   - No data collection, no telemetry
   - You can stop the tunnel at any time

5. Your Rights
   - Cancel installation at any time
   - Uninstall removes ALL components
   - No hidden files or registry entries

6. Disclaimer
   Provided "as is" without warranty.
   Shanghai UltraDimension Technology Co., Ltd. is not liable for damages.

7. Open Source
   Uses Rospo (MIT), PRODUCT_NAME CLI, Node.js (MIT),
   and other open-source components.

For security review: support@ultradimension.cn
EOL
)"
    license_text="${license_text//PRODUCT_NAME/$PRODUCT_NAME}"
    license_text="${license_text//INSTALLER_VERSION/$INSTALLER_VERSION}"

    show_license "$license_text"
    if [[ $? -ne 0 ]]; then
        echo "LICENSE_DECLINED"
        exit 1
    fi

    # Phase 2: License token
    local license_token
    license_token="$(read_license_token)"

    if [[ -z "$license_token" ]]; then
        local input
        if ! input=$(show_token_input); then
            echo "TOKEN_CANCELLED"
            exit 1
        fi
        license_token="$(echo "$input" | tr -d '[:space:]')"
    fi

    echo "Validating license..."
    local validation
    validation="$(validate_license "$license_token")"
    if [[ "$validation" != OK:* ]]; then
        osascript -e "
        display dialog \"License validation failed. Please download the installer from the official service portal.\" ¬
            with title \"License Failed\" ¬
            buttons {\"Close\"} ¬
            with icon stop
        " 2>/dev/null
        exit 1
    fi
    echo "License OK: ${validation#OK:}"

    # Save token for install script
    echo "$license_token" > "$WORK_DIR/payload/license_token.txt"

    # Phase 3: Run the platform install script
    local install_script="$WORK_DIR/payload/install.sh"
    if [[ ! -f "$install_script" ]]; then
        echo "FATAL: install.sh not found in payload"
        exit 1
    fi
    chmod +x "$install_script"

    # Export vars for install script
    export PRODUCT_ID
    export PRODUCT_NAME

    echo "Starting installation..."
    # Unix installers use a user-owned tunnel directory under $HOME, so the
    # target user identity must be preserved. Running through administrator
    # privileges would switch HOME to root and install the CLI for the wrong user.
    "$install_script" --silent 2>&1 | while IFS= read -r line; do
        echo "[install] $line"
    done
    local rc=${PIPESTATUS[0]}

    if [[ $rc -eq 0 ]]; then
        show_done "true"
        exit 0
    else
        show_done "false"
        exit 1
    fi
}

main "$@"
